package index.Btree;

import java.io.FileNotFoundException;


import file_rw.FileRW;

public class BtreeNode  implements BtreeNodeInterface {
	
	public int tag ; // ҳ��
	public int leaf_num ; //Ԫ�ظ���
	public int leaf_rightson ; //����ָ��
	public int leaf_or ; //�Ƿ���Ҷ�ӽڵ�
    
	public int leaf_key ; //Ԫ����ֵ
	public int leaf_pagenum ; //��ԪԪ��ָ��
	
	public int leaf_parent ;//���ڵ�
	public int leaf_brother;//ǰһ�����

	public int[] key ; //Ԫ����ֵ
	public int[] pagenum ; //��ԪԪ��ָ��
	
	public static byte[] nodeByte ;//�������ڵ���ֽ�
	
	
	
	
	public BtreeNode(int blockid) {

		 nodeByte = new byte[k_leaf];
		 getNode(blockid); 
		 
		 tag = blockid;
		 leaf_num = byte2int(nodeByte,k_leaf_head_num);
		 leaf_rightson = byte2int(nodeByte,k_leaf_head_num+k_leaf_head_count);
		 leaf_or = byte2int(nodeByte,k_leaf_head_num+k_leaf_head_count+k_leaf_head_rightson);
		 leaf_parent = byte2int(nodeByte,k_leaf_head_num+k_leaf_head_count+k_leaf_head_rightson+k_leaf_head_orleaf);		  		 
		 leaf_brother = byte2int(nodeByte,k_leaf_head_num+k_leaf_head_count+k_leaf_head_rightson+k_leaf_head_orleaf+k_leaf_head_parent);
		
		 
		 leaf_key = 0;
		 leaf_pagenum = 0;		 
		 key = new int[ k_n+1];
		 pagenum = new int[ k_n+1];		 
		 for(int i =0;i<leaf_num;i++){
			 key[i] = byte2int(nodeByte,k_leaf_head+i*(k_leaf_num+k_leaf_pagenum)+k_leaf_pagenum);
		 }
		 for(int j = 0;j<leaf_num;j++){
			 pagenum[j] = byte2int(nodeByte,k_leaf_head+j*(k_leaf_num+k_leaf_pagenum));
		 }
	}
	
	
	public void getNode(int tag){	
		FileRW fr = new FileRW();
		try {
			nodeByte = fr.readBytes(BtreeInterface.index_file_addr, BtreeInterface.block_head_size+BtreeInterface.block_head_bmp*4+(tag-1)*k_leaf, k_leaf);
			for(int i =0;i<nodeByte.length;i++){
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}	
	}
	//bytes to int �����int����ڵ�λ
	public static int  byte2int(byte[] bytes,int start){
		 int num = bytes[3+start] & 0xFF;  
		    num |= ((bytes[2+start] << 8) & 0xFF00);  
		    num |= ((bytes[1+start] << 16) & 0xFF0000);  
		    num |= ((bytes[0+start] << 24) & 0xFF000000);  
		    return num;   
	}
	
	public static byte[] int2byte(int i) {  
	    byte[] bt = new byte[4];  
	    bt[3] = (byte) (0xff & i);  
	    bt[2] = (byte) ((0xff00 & i) >> 8);  
	    bt[1] = (byte) ((0xff0000 & i) >> 16);  
	    bt[0] = (byte) ((0xff000000 & i) >> 24);  
	    return bt;  
	}  

	
	
	


	  
	@Override
	public int getTag() {
		return tag;
	}

	@Override
	public int getNum() {
		return leaf_num;
	}

	@Override
	public int getRighson() {
		return leaf_rightson;
	}
	
	@Override
	public int getOrleaf() {
		return leaf_or;
	}
	
	@Override
	public int getParent() {
		return leaf_parent;
	}

	@Override
	public int getKey(int i) {
		return key[i-1];
	}

	@Override
	public int[] getkey() {
		int[] kes = new int[leaf_num];
		for(int i=0;i<leaf_num;i++){
			kes[i] = key[i];
		}		
		return kes;
	}

	@Override
	public int getPageNum( int i) {
		return pagenum[i-1];
	}

	@Override
	public int[] getPageNum() {
		int[] kes = new int[leaf_num];
		for(int i=0;i<leaf_num;i++){
			kes[i] = pagenum[i];
		}	
		return kes;
	}

	@Override
	public int getBrother() {
		return leaf_brother;
	}

	@Override
	public void setTag(int tags) {
		tag = tags;
	}

	@Override
	public void setNum(int i) {
		leaf_num = i;
	}

	@Override
	public void setRighson(int i) {
		leaf_rightson = i;
	}
	
	@Override
	public void setOrleaf(int i) {
		leaf_or = i;
	}
	
	@Override
	public void setParent(int i) {
		leaf_parent = i;
	}

	@Override 
	public void setKey(int i,int l) {
		key[i-1] = l;
	}

	@Override
	public void setKey(int[] res) {
		key = res;
	}

	@Override
	public void setPageNum(int i,int l) {
		pagenum[i-1] = l;
	}

	@Override
	public void setPageNum(int[] res) {
		pagenum = res;
	}

	@Override
	public void setBrother(int i) {
		leaf_brother = i;
	}
	
	public void setnodeByte(){
		
		int i,j;
		byte[] temp = new byte[4];
		temp = int2byte(leaf_num);
		for(i = 0;i<4;i++){
			nodeByte[i+4] = temp[i];
		}///leaf_num
		temp = int2byte(leaf_rightson);		
		for(i = 0;i<4;i++){
			nodeByte[i+8] = temp[i];
		}///leaf_rightson
		temp = int2byte(leaf_or);
		for(i = 0;i<4;i++){
			nodeByte[i+12] = temp[i];
		}///leaf_or
		temp = int2byte(leaf_parent);
		for(i = 0;i<4;i++){
			nodeByte[i+16] = temp[i];
		}///leaf_parent
		temp = int2byte(leaf_brother);
		for(i = 0;i<4;i++){
			nodeByte[i+20] = temp[i];
		}///leaf_brother
		
		byte[] temp2 = new byte[key.length*4];
		
		for(i = 0;i<key.length;i++){
			temp2 = int2byte(key[i]);
			for(j=0;j<4;j++){
				nodeByte[i*8+72+4+j] = temp2[j];
			}
		}///key
		for(i = 0;i<pagenum.length;i++){
			temp2 = int2byte(pagenum[i]);
			for(j=0;j<4;j++){
				nodeByte[i*8+72+j] = temp2[j];
			}
		}///pagenum
	}
	
	@Override
	public void setNode(int num, int rightson, int orleaf,int parent,int brother,int[] keys,int[] pagenums) {
		setTag(tag);
		

		if(num!=-1){
			setNum(num);
		}
		if(rightson!=-1){
			setRighson(rightson);
		}
		if(orleaf!=-1){
			setOrleaf(orleaf);
		}
		if(parent!=-1){
			setParent(parent);
		}
		if(brother!=-1){
			setBrother(brother);
		}
		if(keys!=null){
			setKey(keys);
		}
		if(pagenums!=null){
			setPageNum(pagenums);		
		}
		setnodeByte();	

		FileRW fr = new FileRW();
		try {
			fr.writeBytes(BtreeInterface.index_file_addr, BtreeInterface.block_head_size+BtreeInterface.block_head_bmp*4+(tag-1)*k_leaf, nodeByte);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}	
	}
}
